<?php
/**
 * 退款事件模型
 * @author Max.Yu <max@jipu.com>
 */

namespace Admin\Event;

class RefundEvent{

  /**
   * 执行退款
   * @param array $ids 订单编号集合
   * @param string $dotype 执行类型（cancel取消订单，refund退款）
   * @return array 执行结果
   */
  public function doit($ids, $dotype = 'cancel'){
    $return_data = array('code' => 300);
    $map['id'] = array('in', $ids);
    if(M('Order')->where($map)->setField('o_status', ($dotype == 'cancel' ? 404 : 303))){
      //商户处理
      $order_sn = getOrderSnByOrderId($ids[0]);
      $where['order_sn'] = array('eq',$order_sn);
      M('StoreOrder')->where($where)->setField('o_status', ($dotype == 'cancel' ? 404 : 303));
      
      //处理库存和退款
      $order_lists = D('Order')->lists($map);
      if($order_lists){
        foreach($order_lists as $key => $value){
          //商品库存处理
          $order_items = get_order_item($value['id']);
          if($order_items){
            $item_model = M('Item');
            foreach($order_items as $item){
              $item_model->where('id='.$item['item_id'])->setInc('stock', $item['quantity']);
            }
          }
          //第三方退款处理
          if($value['total_amount'] > 0){
            $payment = M('Payment')->getById($value['payment_id']);

            $payment_return = json_decode($payment['payment_return'], true);
            $trade_no = $payment_return['trade_no'];
            if(empty($trade_no)){
              $trade_no = $payment_return['transaction_id'];
            }
            if(empty($trade_no)){
              $trade_no = M('Payment')->getFieldByOrderId($value['id'], 'payment_sn');
            }
            $refund_data = array(
              'uid' => $value['uid'],
              'order_id' => $value['id'],
              'payment_type' => $payment['payment_type'],
              'trade_no' => $trade_no,
              'refund_type' => 'item',
              'amount' => $value['total_amount'],
              'detail' => '购物退款'
            );
            D('Refund')->update($refund_data);
          }

          //账户余额返还
          if($value['finance_amount'] > 0){
            $this->refundFinance($value['id']);
          }

          //分销订单取消返现
          if($value['sdp_uid'] > 0){
            foreach($order_items as $keys=>$vals){
                $shop = M('shop')->where(array('secret'=>$vals['sdp_code']))->find();
                $line = M('SdpRecord')->where(array('sdp_uid' => $shop['uid'], 'order_id' => $value['id'],'item_id'=> $vals['item_id']))->field('sum(cashback_amount) as sum_amount')->find();
                if($line){
                    $finance_data = array(
                            'uid' => $shop['uid'],
                            'order_id' => $value['id'],
                            'type' => 'sdp_refund',
                            'amount' => $line['sum_amount'],
                            'flow' => 'out',
                            'memo' => '分销订单退款',
                            'create_time' => NOW_TIME
                    );
                    if(M('Finance')->add($finance_data)){
                       M('Member')->where('uid = '.$shop['uid'])->setDec('finance', $line['sum_amount']);
                    }
                }
            }

          }

          //推广者联盟取消返现 BUDDHA
          $res_data = M('Finance')->where(array('order_id'=>$value['id'],'type'=>'union_order','flow'=>'in'))->select();
          if ($res_data) {
            foreach ($res_data as $fkey => $fval) {

              $memo = explode('返现',$fval['memo']);
              $string = $memo[0].'退款'.$memo[1];

              $refund_finance = array(
                  'uid'=>$fval['uid'],
                  'order_id' => $fval['order_id'],
                  'type' => 'union_refund',
                  'amount' => $fval['amount'],
                  'flow' => 'out',
                  'memo' => $string,
                  'create_time' => NOW_TIME
              );
              if (M('Finance')->add($refund_finance)) {
                M('Member')->where('uid = '.$fval['uid'])->setDec('finance', $fval['amount']);
              }
            }
          } 
        }
      }


      //action_log('cancel_order', 'Order', $id, UID);
      $return_data = array('code' => 200, 'info' => '订单'.($dotype == 'cancel' ? '取消' : '退款').'成功！');
    }else{
      $return_data = array('code' => 300, 'info' => '订单'.($dotype == 'cancel' ? '取消' : '退款').'失败！');
    }
    return $return_data;
  }

  /**
   * 退款成功后，更新退款订单
   */
  public function afterRefundSuccess($refund_no, $refund_info){
    //获取退款订单信息
    $refund_details = explode('#', $refund_info['details']);
    set_log('refund_cash_order',$refund_info,'退款成功');
    add_wechat_log($refund_details, 'refund-details');
    //现金操作
    $store_cash_event = A('Home/storeCash','Event');
    if($refund_details){
      foreach($refund_details as $key => $value){
        $refund_item = explode('^', $value);
        $refund_map = array(
          'trade_no' => $refund_item[0],
          'refund_no' => $refund_no
        );
        $refund_orders = M('Refund')->where($refund_map)->select();
        foreach($refund_orders as $refund_order){
            if(($refund_item[2] == 'SUCCESS') && ($refund_order['refund_status'] == 2)){
            $refund_data = array(
              'refund_status' => 3,
              'refund_return' => json_encode($refund_info)
            );
            add_wechat_log($refund_data, 'refund-data');
            M('Refund')->where('id = '.$refund_order['id'])->save($refund_data);
            if($refund_order['type'] == 2){
              $this->handlejoin($refund_order['order_id']);
            }
            //退款时交易记录
            $order_sn = M('StoreOrder')->where('id='.$refund_order['order_id'])->getField('order_sn');
            //修改商户订单状态
            M('StoreOrder')->where(array('id'=>$refund_order['order_id']))->setField('o_status', 303);         
            //查询订单个数
            $count = A('Home/Order','Event')->checkOrderCount($refund_order['order_id']);
            $store_count = A('Home/Order','Event')->checkOrderStatusCount(array('o_status'=>303),$order_sn);
            if ($count == 1 || ($count-1) == $store_count) {
               M('Order')->where(array('order_sn'=>$order_sn))->setField('o_status', 303);
            }
          }
        }
      }
    }
  }

  /**
   * [handlejoin 处理团购退款]
   * @param  [type] $order_id [description]
   * @return [type]           [description]
   */
  function handlejoin($order_id){
    if($result = M('Join_order')->alias('a')->join('RIGHT JOIN __JOIN_LIST__ b on a.join_id=b.id')->where('a.id='.$order_id.' and b.status=2')->getField('a.join_id')){
      M('Join_list')->where('id='.$result)->setField('status' ,3);
    }
  }

   /**
    * 推广分销返现 取消
    * @param  [type] $orderid [description]
    * @return [type]          [description]
    */
  function series_refund($orderid){
    $where['type']   = array('in' ,array('union_order')) ;
    $where['flow']   = 'in' ;
    $where['status'] = 0 ;
    $where['order_id']     = $orderid ;
    $result = M('Finance')->where($where)->getField('id' ,true);
    if(!$result){
      return false;
    }
    $map = implode(',' , $result);
    M('Finance')->where('id in ('.$map.')')->setField('status' , '2');
    $users = M('Finance')->where('id in ('.$map.')')->field('uid,amount')->select();
    foreach($users as $k => $v){
      M('Member')->where('uid ='.$v['uid'])->setDec('finance' ,$v['amount']);
    }
  }
  /**
   * 账户余额返还处理
   */
  public function refundFinance($order_id, $memo = '订单退款'){
    $order = M('Order')->find($order_id);
    if($order && $order['finance_amount'] > 0){
      //更新用户账户余额
      $update_member = M('Member')->where('uid = '.$order['uid'])->setInc('finance', $order['finance_amount']);
      if($update_member){
        //增加更新记录
        $data_finance = array(
          'uid' => $order['uid'],
          'order_id' => $order['id'],
          'type' => 'refund',
          'amount' => $order['finance_amount'],
          'flow' => 'in',
          'memo' => $memo,
          'create_time' => NOW_TIME
        );
        $update_finance = M('Finance')->add($data_finance);
      }/*else{
        return false;
      }
      return true;*/
    }/*else{
      return false;
    }*/
  }

  /**
   * 优惠券返还处理
   */
  public function refundCoupon($order_id){
    $res = M('CouponUser')->where(array('order_id'=>$order_id))->find();
    if ($res) {
      //优惠券使用记录
      $data = array(
          'status'=>0,
          'use_time'=>0,
          'use_amount'=>0,
          'order_sn'=>''
        );
      M('CouponUser')->where(array('order_id'=>$order_id))->save($data);
    }
  }

  /**
   * 礼品卡返还处理
   */
  public function refundCard($order_id){
    $order = M('Order')->find($order_id);
    if($order && $order['is_use_card'] == 1){
      //更新card_user表
      $card_id = $order['card_id'];
      $map_user['card_id'] = array('IN', $card_id);
      $data_user = array(
        'status' => 0,
        'use_time' => ''
      );
      $update_card_user = D('CardUser')->where($map_user)->save($data);

      //更新card表
      $map_card['id'] = array('IN', $card_id);
      $data_card = array(
        'balance' => array('exp', 'balance + '.$order['card_amount']),
        'use_time' => '',
        'is_use' => 0
      );
      $update_card = M('Card')->where($map_card)->save($data_card);
      /*if($update_card_user && $update_card){
        return true;
      }else{
        return false;
      }*/
    }
  }
  
  /**
   * 积分退还
   * @param  [type] $order_id [description]
   * @return [type]           [description]
   */
  public function refundScore($order_id){
    $res = M('ScoreLog')->where(array('order_id'=>$order_id))->find();
    if ($res) {
      //记录积分返还日志
      $data = array(
          'uid' => $res['uid'],
          'order_id' => $order_id,
          'order_sn' => $res['order_sn'],
          'type' => 'in',
          'amount' => $res['amount'],
          'memo' => '购物订单退款返还积分',
          'create_time' => NOW_TIME,
        );
        M('ScoreLog')->add($data);
        M('Member')->where(array('uid' => $res['uid']))->setInc('score', $res['amount']);
    }
  }
   
  /**
   * 单笔退款
   * @param int $refund_id 退款记录ID
   */
  public function dealRefund($refund_id){
    $return_data = array('status' => 0, 'info' => '退款出错了');
    $data = M('Refund')->find($refund_id);
    if($data['type'] ==1 ){
      //$data['order'] = M('Order')->find($data['order_id']);
      $data['order'] = M('StoreOrder')->find($data['order_id']);
      //通过order_sn查询店铺微信退款占比 start
      $order = M('Order')->where(array('order_sn'=>$data['order']['order_sn']))->find();
      $store_other = unserialize($order['store_other']);
      $store_amount = $store_other['store_amount'];
      foreach ($store_other['store_amount'] as $key => $value) {
        $total_amount += $value;
      }
      //通过order_sn查询店铺微信退款占比 end
    }else{
      $data['order'] = M('Join_order')->find($data['order_id']);
    }
    if($data['refund_status'] != 2){
      $return_data['info'] = '当前状态，不可进行退款操作';
      return $return_data;
    }
    //微信退款（公众号支付+APP支付）
    if($data['payment_type'] == 'wechatpay' || $data['payment_type'] == 'wechatAppPay'){
      $pay_data = M('Payment')->getById($data['order']['payment_id']);
      //需要退款金额 普通订单
      if ($data['type'] == 1) {
        $refund_fee = $pay_data['payment_amount'] * $data['order']['total_amount'] / $total_amount;
        $refund_fee = sprintf("%.2f",$refund_fee);
        $refund_amount = ($refund_fee * 100 < 1) ? 0 : $refund_fee;
        if ($refund_amount == 0) {
          $return_data['info'] = '当前可退款金额不足,不能退款';
          return $return_data;
        }
      }
      $out_refund_no = date('YmdHis').mt_rand(100000, 999999);
      import('Org.Wechat.Pay.WxPayPubHelper', '', '.php');
      $payment_way = C('WECHATPAY');
      $refund_api = new \Refund_pub();
      //Buddha APP退款特殊处理
      if($data['payment_type'] == 'wechatAppPay'){
        $payment_way = C('WECHATAPPPAY');
        $refund_api = new \Refund_pub('APP');
      }
      $refund_api->setParameter("transaction_id", $pay_data['payment_sn']); //
      $refund_api->setParameter('out_refund_no', $out_refund_no);
      $refund_api->setParameter('total_fee', $pay_data['payment_amount']*100);
      if ($data['type'] == 1) {//普通购物流程
        $refund_api->setParameter('refund_fee', $refund_amount*100);
      }else{//拼团购物
        $refund_api->setParameter('refund_fee', $data['order']['total_amount']*100);
      }
      $refund_api->setParameter('op_user_id', $payment_way['mch_id']);
      //退款判断 当日下单当日退款（使用未结算资金退款【默认】）|| 非当日下单退款（可用余额退款） BUDDHA 20170518
       //查询当前退款订单的支付时间 
       if ($data['type'] == 1) {
         $payment_day = date('Ymd',$data['order']['payment_time']);
       }else{
        $payment_day = date('Ymd',$data['order']['paytime']);
       }
       
       $now_day = date('Ymd',NOW_TIME);
       if ($now_day > $payment_day) {
         $refund_api->setParameter('refund_account', 'REFUND_SOURCE_RECHARGE_FUNDS' );
       }
      //退款
      $res = $refund_api->getResult();
      //退款失败分析 
      if ($res['result_code'] == 'FAIL' ) {
        switch ($res['err_code']) {
          //超过退款期限
          case 'TRADE_OVERDUE':
            $return_data['info'] = $res['err_code_des'];
            break;
          //余额不足
          case 'NOTENOUGH':
            $return_data['info'] = $res['err_code_des'];
            break;
          //其他
          default:
            $return_data['info'] = $res['err_code_des'];
            break;
        }
        return $return_data;
      }
      
      if($res['return_code'] == 'FAIL'){
        $refund_query_api = new \RefundQuery_pub();
        $refund_query_api->setParameter("transaction_id", $pay_data['payment_sn']); //openid
        //退款状态
        $res_query = $refund_query_api->getResult();
      }
      if($res['return_code'] == 'SUCCESS' || $res_query['result_code'] == 'SUCCESS'){
        $save_data = array(
          'refund_no' => $out_refund_no,
          'refund_status' => 3,
          'refund_return' => json_encode($res),
        );
        M('Refund')->where(array('id' => $data['id']))->save($save_data);

        if ($data['type'] == 2) {//拼团修改状态
          $this->handlejoin($data['order_id']);
        }
        //修改商户订单状态
        M('StoreOrder')->where(array('id'=>$data['order_id']))->setField('o_status', 303);
        
        //查询订单个数
        $count = A('Home/Order','Event')->checkOrderCount($data['order_id']);
        $order_sn = M('StoreOrder')->where(array('id'=>$data['order_id']))->getField('order_sn');
        $store_count = A('Home/Order','Event')->checkOrderStatusCount(array('o_status'=>303),$order_sn);

        if ($count == 1 || ($count -1) == $store_count ) {
          M('Order')->where(array('order_sn'=>$data['order']['order_sn']))->setField('o_status', 303);
        }
        
        
        //推广分销返现 返回
        $this->series_refund($order['id']);

        //账户余额支付返回
        //$this->refundFinance($data['order_id']);

        //优惠券支付返回
        //$this->refundCoupon($order_id);

        //礼品卡返回处理
        //$this->refundCard($order_id);

        //退款时交易记录
        //$this->refundLog($refund_id,$order_id);
        //退款时，商铺记录
        //$this->refundOrderPaid($order_id);
    
        $store_cash_event = A('Home/StoreCash','Event');
        //订单支付后的资金流水 
        $store_cash_event->orderPaid($data['order']['order_sn'],2,$data['store_id']);

        //分销店铺的商户流水
        if( C('DIS_ORDERSTATUS') == 1){
          $store_cash_event->distribute($order['id'],2,$data['store_id']);
        }
        //商户分销店铺流水
        $store_cash_event->sdpOrder($order['id'],2,$data['store_id']);

        return array('status' => 1, 'info' => '退款发起成功');
      }else{
        $return_data['info'] = $res['return_msg'];
      }
    }
    return $return_data;
  }

  /**
   * 退款时，交易记录
   * @param  [type] $data [description]
   * @return [type]       [description]
   */
  public function refundLog($refund_id,$order_id){

    //退款记录表中数据
    $data = M('Refund')->find($refund_id);
    //订单表中数据 订单号
    $order_sn = M('Order')->where(array('order_id'=>$order_id))->getField('order_sn');

    //新增交易记录
    $transaction_data = array(
      'uid' => $data['uid'],
      'order_id' => $order_id,
      'order_sn' => $order_sn,
      'flowid' => create_sn(),
      'number' => $data['trade_no'],
      'type' => '退款',
      'mode' => $data['payment_type'],
      'amount' => $data['amount'],
      'flow' => 'in',
      'memo' => '购物退款',
      'transaction_time'=>NOW_TIME,
      'create_time'=>NOW_TIME,
      'status' => 1,
    );
    D('Transaction')->add($transaction_data);
  }

  /**
   * 退款时，店铺现金记录
   * @param  [type] $order_id [description]
   * @return [type]           [description]
   */
  public function refundOrderPaid($order_id){
    $data = M('storeCash')->where(array('order_id'=>$order_id))->select();
    foreach ($data as $key => $value) {
      //订单收款
      if ($value['flow'] == 'in') {
        $re_data = array(
          'uid'=>$value['uid'],
          'store_id'=>$value['store_id'],
          'order_id'=>$order_id,
          'trade_sn'=>$value['trade_sn'],
          'type'=>'refund',
          'trade_type'=>$value['trade_type'],
          'flow'=>'out',
          'amount'=>$value['amount'],
          'ctime'=>NOW_TIME,
          'remark'=>'订单退款',
          'status'=>1
          );
      }else{
        $_data = array(
          'uid'=>$value['uid'],
          'store_id'=>$value['store_id'],
          'order_id'=>$order_id,
          'trade_sn'=>$value['trade_sn'],
          'type'=>'refund',
          'trade_type'=>$value['trade_type'],
          'flow'=>'in',
          'amount'=>$value['amount'],
          'ctime'=>NOW_TIME,
          'remark'=>'佣金返还',
          'status'=>1
          );
      }
    }
    M('StoreCash')->add($re_data);
    M('StoreCash')->add($_data);
  }
}
